<template>
  <div class="upload-page">
    <div class="upload-header">
      <el-button @click="goBack" icon="ArrowLeft" text>返回</el-button>
      <h2>上传底单</h2>
    </div>

    <div class="search-bar">
      <el-input
        v-model="searchQuery.regNo"
        placeholder="请输入报名编号"
        class="reg-no-input"
      >
        <template #prepend>
          <el-input
            v-model="searchQuery.studentInfo"
            placeholder="请输入姓名"
            class="name-input"
          />
        </template>
        <template #append>
          <div class="search-btn" @click="handleSearch">搜索</div>
        </template>
      </el-input>
    </div>

    <div
      class="upload-content"
      v-infinite-scroll="loadMore"
      :infinite-scroll-disabled="loading || noMore"
    >
      <div class="upload-tip">支持jpg/png文件，且不超过5MB</div>
      <div class="cards-container">
        <el-card
          v-for="item in allParticipant"
          :key="item.teamId"
          class="participant-card"
        >
          <div class="card-layout">
            <div class="info">
              <p class="name">ID：{{ item.id }}</p>
              <p class="team-id">报名编号：{{ item.regNo }}</p>
              <p class="team-id">学生信息：{{ item.studentInfo }}</p>
              <div class="upload-buttons">
                <el-upload
                  :action="uploadUrl"
                  :show-file-list="false"
                  :http-request="(file) => handleUpload(file, item)"
                  :before-upload="beforeUpload"
                  :on-success="(res) => handleUploadSuccess(res, item)"
                  :on-error="handleUploadError"
                  accept="image/*"
                >
                  <el-button size="small" type="primary">
                    <el-icon> <Upload /> </el-icon>选择图片
                  </el-button>
                </el-upload>
                <!-- <el-button size="small" type="success" @click="openCamera(item)">
                  <el-icon>
                    <Camera />
                  </el-icon>拍照上传
                </el-button> -->
              </div>
            </div>
            <div class="upload-section">
              <div
                class="image-container"
                :class="{ 'has-image': item.basePhoto }"
              >
                <el-image
                  :preview-teleported="true"
                  v-if="item.basePhoto"
                  :src="`http://101.200.220.56${item.basePhoto}`"
                  :preview-src-list="[`http://101.200.220.56${item.basePhoto}`]"
                  fit="cover"
                >
                  <template #error>
                    <div class="image-slot">
                      <el-icon>
                        <Picture />
                      </el-icon>
                      <span>加载失败</span>
                    </div>
                  </template>
                </el-image>
                <div v-else class="upload-placeholder">
                  <el-icon>
                    <Picture />
                  </el-icon>
                  <span>暂无图片</span>
                </div>
              </div>
            </div>
          </div>
        </el-card>
      </div>
      <div class="loading-status" v-if="loading || noMore">
        <p v-if="loading">加载中...</p>
        <p v-if="noMore">没有更多数据了</p>
      </div>
    </div>
  </div>

  <!-- 拍照对话框 -->
  <el-dialog
    v-model="cameraDialogVisible"
    title="拍照上传"
    width="500px"
    :close-on-click-modal="false"
  >
    <div class="camera-container">
      <video ref="video" autoplay playsinline></video>
      <canvas ref="canvas" style="display: none"></canvas>
    </div>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="closeCamera">取消</el-button>
        <el-button type="primary" @click="takePhoto">拍照</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script setup>
import { ref, onMounted, computed } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
// 添加 infinite-scroll 指令
import { ElInfiniteScroll } from 'element-plus'

import { ArrowLeft, Upload, Camera, Picture } from '@element-plus/icons-vue'
import {
  droneApi,
  fireApi,
  gobangApi,
  obstacleApi,
  logisticsApi,
  infoApi,
} from '@/api/modules'

const router = useRouter()
const allParticipant = ref([])
const apiHandle = {
  drone: droneApi,
  fire: fireApi,
  obstacle: obstacleApi,
  logistics: logisticsApi,
  gobang: gobangApi,
  info: infoApi,
}

const { batchNo, groupCategory, playType, activeTab, status } =
  router.currentRoute.value.query
const queryParams = { batchNo, groupCategory, playType, status }
const currentPage = ref(1)
const pageSize = ref(10)
const total = ref(0)

const goBack = () => {
  router.back()
}

// 搜索相关代码
const searchQuery = ref({
  studentInfo: '',
  regNo: '',
})
let searchParams = {}

const handleSearch = (key, val) => {
  searchParams = {
    studentInfo: searchQuery.value.studentInfo,
    regNo: searchQuery.value.regNo,
  }
  getTableData()
}

//覆盖默认上传行为
const handleUpload = async (file, item) => {
  const data = {
    ...queryParams,
    regNo: item.regNo,
    id: item.id,
  }
  const formData = new FormData()
  formData.append('file', file.file)
  formData.append('data', JSON.stringify(data))
  const res = await infoApi.uploadImage.post(formData)
  // if (res.code === 200) {
  //   this.$message.success('上传成功');
  // } else {
  //   this.$message.error('上传失败');
  // }
  return res
}
const handleUploadSuccess = (res, participant) => {
  participant.basePhoto = res.url
  ElMessage.success('上传成功')
}

const handleUploadError = () => {
  ElMessage.error('上传失败，请重试')
}

const uploadUrl = `${import.meta.env.VITE_API_URL}/upload` // 替换为实际的上传地址
const cameraDialogVisible = ref(false)
const video = ref(null)
const canvas = ref(null)
const currentItem = ref(null)
let stream = null

// 打开摄像头
const openCamera = async (item) => {
  currentItem.value = item
  try {
    stream = await navigator.mediaDevices.getUserMedia({
      video: { facingMode: 'environment' },
    })
    video.value.srcObject = stream
    cameraDialogVisible.value = true
  } catch (err) {
    ElMessage.error('无法访问摄像头')
    cameraDialogVisible.value = false
  }
}

// 关闭摄像头
const closeCamera = () => {
  if (stream) {
    stream.getTracks().forEach((track) => track.stop())
  }
  cameraDialogVisible.value = false
  currentItem.value = null
}

// 拍照
const takePhoto = () => {
  const ctx = canvas.value.getContext('2d')
  canvas.value.width = video.value.videoWidth
  canvas.value.height = video.value.videoHeight
  ctx.drawImage(video.value, 0, 0)

  canvas.value.toBlob(async (blob) => {
    const data = {
      ...queryParams,
      regNo: currentItem.value.regNo,
    }
    const file = new File([blob], 'photo.jpg', { type: 'image/jpeg' })
    const formData = new FormData()
    formData.append('file', file)
    formData.append('data', JSON.stringify(data))
    try {
      const res = await infoApi.uploadImage.post(formData)
      if (res.code === 200) {
        handleUploadSuccess(result, currentItem.value)
      }
      // const response = await fetch(uploadUrl, {
      //   method: 'POST',
      //   body: formData,
      // })
      // const result = await response.json()
    } catch (error) {
      handleUploadError()
    }

    closeCamera()
  }, 'image/jpeg')
}

// 上传前验证
const beforeUpload = (file) => {
  const isImage = file.type.startsWith('image/')
  const isLt5M = file.size / 1024 / 1024 < 5

  if (!isImage) {
    ElMessage.error('只能上传图片文件!')
    return false
  }
  if (!isLt5M) {
    ElMessage.error('图片大小不能超过 5MB!')
    return false
  }
  return true
}

const loading = ref(false)
const noMore = ref(false)

// 修改获取数据方法
const getTableData = async (isLoadMore = false) => {
  if (loading.value) return
  loading.value = true

  try {
    const res = await apiHandle[activeTab].queryPageList.post({
      ...queryParams,
      pageNum: currentPage.value,
      pageSize: pageSize.value,
      ...searchParams,
    })

    if (res.code !== 200) {
      ElMessage.error(res.message || '获取列表失败')
      return
    }
    if (res.data.pageNum === 1) {
      allParticipant.value = []
    }

    const list = res.data.list || []
    allParticipant.value = isLoadMore
      ? [...allParticipant.value, ...list]
      : list
    total.value = res?.data?.total || 0
    noMore.value = allParticipant.value.length >= total.value
  } catch (error) {
    console.error('获取数据失败:', error)
  } finally {
    loading.value = false
  }
}

// 加载更多数据
const loadMore = async () => {
  if (noMore.value || loading.value) return
  currentPage.value++
  await getTableData(true)
}

// 重置分页
const resetPagination = () => {
  currentPage.value = 1
  noMore.value = false
  allParticipant.value = []
}

onMounted(() => {
  resetPagination()
  getTableData()
})
</script>

<style lang="scss" scoped>
.upload-page {
  height: 100vh;
  display: flex;
  flex-direction: column;
  background-color: #f5f7fa;
  padding: 0 16px;
  transition: all 0.3s ease;

  .upload-header {
    display: flex;
    align-items: center;
    margin-bottom: 24px;
    padding: 24px 8px 0 8px;

    h2 {
      margin: 0;
      margin-left: 12px;
      font-size: 24px;
      color: #2c3e50;
      font-weight: 600;
    }
  }

  .upload-content {
    flex: 1;
    overflow-x: hidden;
    overflow-y: auto;

    .upload-tip {
      color: #909399;
      font-size: 14px;
      margin: 16px 8px;
      padding: 8px 16px;
      background-color: #f4f4f5;
      border-radius: 6px;
      display: inline-block;
    }

    .cards-container {
      display: grid;
      gap: 8px;
      padding: 8px 4px;
      margin-bottom: 10px;

      .participant-card {
        border-radius: 12px;
        overflow: hidden;
        box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);

        :deep .el-card__body {
          padding: 10px;
        }

        .card-layout {
          display: flex;
          flex-direction: row;
          gap: 16px;
          align-items: center;

          .info {
            flex: 2;
            display: flex;
            flex-wrap: wrap;
            align-items: flex-start;
            min-width: 120px;

            p {
              width: 45%;
              font-size: 14px;
              font-weight: 600;
              line-height: 19px;
              margin-top: 0;
              margin-bottom: 10px;
              text-align: left;
              color: #2c3e50;
            }

            .team-id {
              font-size: 12px;
              color: #606266;
            }

            :deep .el-button {
              height: 26px;
              padding: 2px 4px;
              font-size: 12px;

              .el-icon {
                margin-right: 4px;
              }

              svg {
                width: 0.8em;
              }

              span {
                margin-left: 0;
              }
            }
          }
        }

        .image-container {
          height: 60px;
          width: 80px;
          background-color: #f8f9fa;
          border-radius: 8px;
          overflow: hidden;
          transition: all 0.3s ease;
          flex: 1;

          .el-image {
            width: 100%;
            height: 100%;
            object-fit: cover;
            transition: transform 0.3s ease;

            &:hover {
              transform: scale(1.05);
            }
          }

          .image-slot {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            height: 100%;
            color: #909399;
            background-color: #f8f9fa;

            .el-icon {
              font-size: 36px;
              margin-bottom: 8px;
            }
          }

          .upload-placeholder {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            height: 100%;
            color: #909399;
            background-color: #f8f9fa;
            cursor: pointer;
            transition: all 0.3s ease;

            &:hover {
              background-color: #f0f2f5;
            }

            .el-icon {
              font-size: 36px;
              margin-bottom: 8px;
            }

            span {
              font-size: 14px;
            }
          }
        }
      }
    }
  }
}

.search-bar {
  margin: 0 8px;
  :deep(.el-input__inner) {
    height: 36px;
    border-radius: 18px;
  }
  :deep(.el-input__prefix) {
    left: 10px;
    display: flex;
    align-items: center;
  }
  :deep .el-input-group__prepend,
  :deep .el-input-group__append {
    padding: 0;
  }
  .reg-no-input :deep .el-input__wrapper {
    border-end-end-radius: 0;
    border-start-end-radius: 0;
  }
  .search-btn {
    background-color: #409eff;
    color: #fff;
    padding: 0 20px;
    height: 100%;
    line-height: 38px;
    border-radius: 0 4px 4px 0;
  }
}

.upload-buttons {
  display: flex;
  gap: 8px;
  margin-top: 8px;
}

.image-container {
  &.has-image {
    border: 2px solid #409eff;
  }
}

.camera-container {
  width: 100%;
  height: 300px;
  display: flex;
  justify-content: center;
  align-items: center;
  background: #000;

  video {
    max-width: 100%;
    max-height: 100%;
  }
}

.loading-status {
  text-align: center;
  padding: 10px 0;
  color: #909399;
  font-size: 14px;
}

.upload-content {
  flex: 1;
  overflow-x: hidden;
  overflow-y: auto;
  // 确保内容区域可以滚动
  overflow-y: auto;
  -webkit-overflow-scrolling: touch; // 增加 iOS 滚动流畅度
}
</style>
